The patches discussed in this section have been applied in several products. The techniques shown are a combination of several presented in the references listed at the end of this paper.
For each "what" item, we need to determine the possible traps to patch. An API reference is indispensible for this purpose. Inside Macintosh and Think Reference contain cross-references and descriptions which help immensely. For instance, we can look up Create(), HCreate(), and DirCreate() to determine which of these traps suit our needs for file and folder creation. We also need to consider PBCreate() and PBHCreate() in their synchronous and asynchronous forms.
As stated previously, the patches are as benign as possible (while still being useful). The intent is to gather, not change, information being passed to or received from the original trap.
The patch code can be very simple. Recording the desired information is easier on the PPC, since you can avoid assembly language completely. However, the 68k assembly required is straightforward.
All of the patches listed below behave in the same manner as the patch code presented in Listing 1:
Listing 1 contains code to patch PBHCreateSync(). The ifndef handles 68k and PPC compiles. Both versions of the function follow a similar sequence.
The source code for the 68k macros is provided on the conference CD, along with the contents of the code listings. In the listings presented in this paper, some code has been removed to save space.
#ifndef powerc asm void MyPBHCreateSync( HParmBlkPtr paramBlock ) { MacroPreProcess move.w kPBHCreateSync, -( sp ); MacroSaveValues move.l oldPBHCreateSyncAddress, a1; MacroCallOriginalTrap } #else OSErr MyPBHCreateSync( HParmBlkPtr paramBlock ) { OSErr theResult; // Hold the params and the trap id // temporarily. CopyHParamBlockValues( paramBlock, kPBHCreateSync ); // Call the original trap. theResult = CallOSTrapUniversalProc( ( UniversalProcPtr ) oldPBHCreateSyncAddress, uppPBFileProcInfo, paramBlock ); // Check result. On success, // save the data. if ( theResult == noErr ) SetArrayElement(); return theResult; } #endifListing 1. Patching PBHCreateSync().
Once the patch receives information regarding the file event (in the form of a PBRec), it needs to store that info until the original trap returns. If the call was successful, the retained data should be enqueued for the background app to process (in the push model), or stored in an array until requested (in the polling model).